package com.zatom.newscore.utils;

import cn.hutool.core.date.DateUtil;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.Module;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.math.RoundingMode;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class U {
    protected static final Logger logger = LoggerFactory.getLogger(com.zatom.newscore.utils.U.class);

    public static ObjectMapper objectMapper = null;

    static {
        objectMapper = ((JsonMapper.Builder) ((JsonMapper.Builder) ((JsonMapper.Builder) ((JsonMapper.Builder) ((JsonMapper.Builder) JsonMapper.builder().configure(MapperFeature.REQUIRE_SETTERS_FOR_GETTERS, true)).configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)).configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)).configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true)).configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)).build();
        objectMapper.registerModule((Module) new ParameterNamesModule())
                .registerModule((Module) new Jdk8Module());
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, (JsonSerializer) new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addSerializer(LocalDate.class, (JsonSerializer) new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addSerializer(LocalTime.class, (JsonSerializer) new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        javaTimeModule.addDeserializer(LocalDateTime.class, (JsonDeserializer) new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        javaTimeModule.addDeserializer(LocalDate.class, (JsonDeserializer) new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
        javaTimeModule.addDeserializer(LocalTime.class, (JsonDeserializer) new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.registerModule((Module) javaTimeModule);
    }

    public static String json(Object value) {
        try {
            return objectMapper.writeValueAsString(value);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
            return null;
        }
    }

    public static <T> T readJson(String json, Class<T> clz) {
        if (json != null)
            try {
                return (T) objectMapper.readValue(json, clz);
            } catch (Exception e) {
                logger.error("json:" + json, e);
            }
        return null;
    }

    public static <T> T readJson(String json, TypeReference<T> reference) {
        if (json != null)
            try {
                return (T) objectMapper.readValue(json, reference);
            } catch (Exception e) {
                logger.error("json:" + json, e);
            }
        return null;
    }

    public static <T> List<T> readListJson(List<String> ls, Class<T> clz) {
        if (ls != null)
            try {
                List<T> r = new ArrayList<>();
                for (String json : ls)
                    r.add((T) objectMapper.readValue(json, clz));
                return r;
            } catch (Exception e) {
                logger.error("json:" + json(ls), e);
            }
        return null;
    }

    public static <T> List<T> readListJson(List<String> ls, TypeReference<T> reference) {
        if (ls != null)
            try {
                List<T> r = new ArrayList<>();
                for (String json : ls)
                    r.add((T) objectMapper.readValue(json, reference));
                return r;
            } catch (Exception e) {
                logger.error("json:" + json(ls), e);
            }
        return null;
    }

    public static Double scale2(Double f) {
        return Double.valueOf((new BigDecimal(f.doubleValue())).setScale(2, RoundingMode.HALF_UP).doubleValue());
    }

    public static Double scale2(Float f) {
        return Double.valueOf((new BigDecimal(f.floatValue())).setScale(2, RoundingMode.HALF_UP).doubleValue());
    }

    public static Double scale(Float f) {
        return Double.valueOf((new BigDecimal(f.floatValue())).setScale(0, RoundingMode.HALF_UP).doubleValue());
    }

    public static Double scale(Double f) {
        return Double.valueOf((new BigDecimal(f.doubleValue())).setScale(0, RoundingMode.HALF_UP).doubleValue());
    }

    public static Integer scale0Int(Double f) {
        return Integer.valueOf((new BigDecimal(f.doubleValue())).setScale(0, RoundingMode.HALF_UP).intValue());
    }

    public static Double scale2RUp(Double f) {
        if (null == f)
            return null;
        Double f2 = Double.valueOf((new BigDecimal(f.doubleValue())).setScale(3, RoundingMode.HALF_UP).doubleValue());
        Double f3 = f2;
        Long l = Long.valueOf(Double.valueOf(f2.doubleValue() * 1000.0D).longValue() % 10L);
        if (l.longValue() > 0L)
            f3 = Double.valueOf((new BigDecimal(f2.doubleValue())).setScale(2, RoundingMode.UP).doubleValue());
        return f3;
    }

    public static Long long100(Double f) {
        if (null == f)
            return null;
        return Long.valueOf((new BigDecimal(f.doubleValue() * 100.0D)).setScale(0, RoundingMode.HALF_UP).longValue());
    }

    public static Integer toInt(Double f) {
        if (null == f)
            return null;
        return Integer.valueOf((new BigDecimal(f.doubleValue())).setScale(0, RoundingMode.HALF_UP).intValue());
    }

    public static boolean isEmpty(Object obj) {
        if (obj == null)
            return true;
        if (obj instanceof String)
            return obj.equals("");
        if (obj instanceof Collection)
            return ((Collection) obj).isEmpty();
        if (obj instanceof Map)
            return ((Map) obj).isEmpty();
        return false;
    }

    public static boolean isNotEmpty(Object obj) {
        return !isEmpty(obj);
    }

    public static String generateCode(long id, int code) {
        return "" + code + code + DateUtil.format((Date) DateUtil.date(), "yyMMddHHmm");
    }

    public static long getIdByCode(String code) {
        return (new BigInteger(code.substring(13))).longValue();
    }
}
